# coding: utf-8
# Author: Legend奇
# @Time： 2020/11/27 上午9:36
from gettext import gettext as _

from tortoise import fields

from base.base_model import MyAbstractBaseModel
from base.choices import ALARM_LEVEL, SNMP_TYPE
from base.constant import AlarmLevel, AlarmStatus
from utils.time import get_current_time_by_microsecond


class Alarm(MyAbstractBaseModel):
    """
            level: 0：致命；1：严重；2：警告；3：提示；4：未知
            status: 0：清除；1：生成；
        """
    LEVEL = (
        (AlarmLevel.FATAL, _('fatal')),
        (AlarmLevel.SERIOUS, _('serious')),
        (AlarmLevel.WARNING, _('warning'))
    )
    STATUS = (
        (AlarmStatus.CREATED, _('not cleared')),
        (AlarmStatus.AUTO_CLEAR, _('auto cleared')),
        (AlarmStatus.MANUAL_CLEAR, _('manual cleared'))
    )

    status = fields.SmallIntField(default=AlarmStatus.CREATED, choices=STATUS)
    firing_value = fields.TextField(default='null', verbose_name='metric data value')
    inactive_value = fields.TextField(default='null', verbose_name='metric data value')
    endpoint = fields.ForeignKeyField('models.Device', null=True, on_delete=fields.CASCADE)
    config = fields.ForeignKeyField('models.AlarmConfig', null=True, on_delete=fields.CASCADE)
    create_timestamp = fields.BigIntField(verbose_name=_('create timestamp'))
    update_timestamp = fields.BigIntField(null=True, verbose_name=_('update timestamp'))
    clear_timestamp = fields.BigIntField(null=True, verbose_name=_('clear timestamp'))
    notify_timestamp = fields.BigIntField(null=True, verbose_name=_('latest notified timestamp'))

    class Meta:
        table = "alarm"
        verbose_name = _('alarm')


class AlarmConfig(MyAbstractBaseModel):
    name = fields.CharField(max_length=128, default='', unique=True, verbose_name=_('alarm config name'))
    level = fields.SmallIntField(default=AlarmLevel.WARNING, choices=ALARM_LEVEL, verbose_name=_('level'))
    for_time = fields.BigIntField(null=True, verbose_name=_('time of duration'))
    message_template = fields.TextField(default='', verbose_name=_('message template'))
    snmp_alarm = fields.SmallIntField(default=0, choices=SNMP_TYPE, verbose_name=_('send snmp alarm'))
    device = fields.ManyToManyField('models.Device')
    judge_sign = fields.CharField(max_length=4, null=False, verbose_name=_('judge sign'))
    statfield = fields.ForeignKeyField('models.StatField', null=True, on_delete=fields.SET_NULL)
    threshold = fields.CharField(default='', max_length=1024, null=False, verbose_name=_('threshold value'))
    alarm_contact_group = fields.ForeignKeyField('models.AlarmContactGroup', null=True, on_delete=fields.RESTRICT)
    tags = fields.TextField(default='null', verbose_name='field filter tags')
    troubleshoot = fields.TextField(default='', verbose_name=_('troubleshoot'))
    notify_duration = fields.IntField(default=60, verbose_name=_('alarm notify duration'))

    class Meta:
        table = 'alarmconfig'
        verbose_name = _('alarm config')


class AlarmSilence(MyAbstractBaseModel):
    name = fields.CharField(max_length=255, default='')
    metrics = fields.TextField(default='[]', verbose_name='metric data value')
    endpoints = fields.TextField(default='[]', verbose_name='metric data value')
    start_timestamp = fields.BigIntField()
    end_timestamp = fields.BigIntField()
    comments = fields.TextField(max_length=1024, default='')

    class Meta:
        table = "alarm_silence"


class AlarmConfigGroup(MyAbstractBaseModel):
    name = fields.CharField(max_length=255, unique=True, verbose_name=_('alarmconfig group name'))
    description = fields.CharField(max_length=1024, blank=True, default='',
                                   verbose_name=_('alarmconfig group description'))
    alarmconfig = fields.ManyToManyField(
        'models.AlarmConfig',
        blank=True,
        table='alarmconfiggroup_config',
        related_name='alarmconfig_group')
    device_group = fields.ManyToManyField(
        'models.DeviceGroup',
        blank=True,
        table='alarmconfig_group_device',
        related_name='device_group')

    class Meta:
        table = 'alarmconfiggroup'
        verbose_name = _('alarm config group')


class AlarmContact(MyAbstractBaseModel):
    name = fields.CharField(max_length=128, default='', unique=True, verbose_name=_('contact name'))
    email = fields.CharField(default='', max_length=128, verbose_name=_('contact email'))
    cellphone = fields.BigIntField(null=True, verbose_name=_('contact cellphone'))

    class Meta:
        table = 'alarmcontact'
        verbose_name = _('alarm contact')


class AlarmContactGroup(MyAbstractBaseModel):
    name = fields.CharField(max_length=255, default='', unique=True, verbose_name=_('contact group name'))
    channel = fields.TextField(max_length=512, default='{}', verbose_name=_('alarm notification channel'))
    description = fields.CharField(max_length=128, default='', verbose_name=_('contact group description'))
    contact = fields.ManyToManyField('models.AlarmContact', table='alarmcontactgroup_contact', related_name='group')

    class Meta:
        table = 'alarmcontactgroup'
        verbose_name = _('alarm group contact group')


class AlarmHandle(MyAbstractBaseModel):
    desc = fields.TextField(default='', verbose_name=_('alarm description'))
    alarm_config = fields.ForeignKeyField('models.AlarmConfig', null=True, on_delete=fields.SET_NULL)

    class Meta:
        table = 'alarm_handle'
        verbose_name = _('alarm handle')


class EmailProxy(MyAbstractBaseModel):
    host = fields.CharField(default='127.0.0.1', max_length=15)
    port = fields.IntField(default=0)
    user = fields.CharField(max_length=255, default='')
    password = fields.CharField(max_length=255, default='')
    tls = fields.BooleanField(default=False)
    ssl = fields.BooleanField(default=False)
    enable_proxy = fields.BooleanField(default=False)
    proxy_host = fields.CharField(default='127.0.0.1', max_length=255)
    proxy_port = fields.IntField(default=25)

    class Meta:
        table = 'email_proxy'
        verbose_name = _('email proxy info')


class SmsApi(MyAbstractBaseModel):
    sms_api = fields.CharField(default='', max_length=255)

    class Meta:
        table = 'sms_api'
        verbose_name = _('sms api info')


class SnmpConfig(MyAbstractBaseModel):
    version = fields.IntField(null=False, verbose_name=_('snmp version'))
    host = fields.CharField(default='', max_length=254)
    config = fields.TextField(default='', verbose_name=_('snmp config'))
    enable = fields.BooleanField(default=False)

    class Meta:
        table = 'snmp_config'
        verbose_name = _('snmp config')


class Plugin(MyAbstractBaseModel):
    name = fields.CharField(null=False, max_length=128, verbose_name=_("pulgin name"))
    script = fields.CharField(null=False, max_length=256, verbose_name=_("pulgin script path"))

    class Meta:
        table = "plugin"
        verbose_name = _("plugin script")


class Job(MyAbstractBaseModel):
    JOB_STATUS = (
        (0, "offline"),
        (1, "online")
    )
    PLUGIN_TYPE = (
        (0, "flux"),
        (1, "python"),
        (2, "shell"),
        (3, "sql")
    )
    name = fields.CharField(null=False, max_length=128, verbose_name=_("job name"))
    schedule_interval = fields.CharField(null=False, max_length=128, verbose_name=_("Scheduling time"))
    # */1 * * * *
    data_src = fields.CharField(null=True, max_length=256, verbose_name=_("data source"))
    # {"type": "influxdb", "db": "oplatform", "rp": "autogen", "measurement": "brd.seccd"}
    data_dst = fields.CharField(null=False, max_length=256, verbose_name=_("Data storage location"))
    # {"type": "influxdb", "db": "oplatform", "rp": "autogen", "measurement": "brd.seccd.merge"}
    plugin_type = fields.SmallIntField(default=0, choices=PLUGIN_TYPE)
    plugin = fields.ForeignKeyField('models.Plugin', null=True, on_delete=fields.SET_NULL)
    status = fields.SmallIntField(default=1, choices=JOB_STATUS)
    create_time = fields.BigIntField(default=get_current_time_by_microsecond, verbose_name=_("create job time"))
    last_time = fields.BigIntField(null=True, verbose_name=_("last executed time"))
    exec_num = fields.IntField(default=0, verbose_name=_("executed num"))

    class Meta:
        table = "job"
        verbose_name = _("job")


class JobLog(MyAbstractBaseModel):
    EXEC_STATUS = (
        (0, "running"),
        (1, "success"),
        (2, "failed")
    )
    job = fields.ForeignKeyField("models.Job", on_delete=fields.CASCADE)
    start_time = fields.BigIntField(default=get_current_time_by_microsecond, verbose_name=_("job execute start time"))
    end_time = fields.BigIntField(null=True, verbose_name=_("job execute end time"))
    status = fields.SmallIntField(default=0, choices=EXEC_STATUS)
    log = fields.TextField(null=True, verbose_name=_("job executed log"))

    class Meta:
        table = "job_log"
        verbose_name = _("job_log")
